"""
K线形态分析：

★早晨之星:=REF(CLOSE,2)/REF(OPEN,2) < 0.95 AND REF(OPEN,1) < REF(CLOSE,2) AND
ABS(REF(OPEN,1)-REF(CLOSE,1))/REF(CLOSE,1)<0.03 AND
CLOSE/OPEN>1.05 AND CLOSE>REF(CLOSE,2);
★黄昏之星:=REF(CLOSE,2)/REF(OPEN,2) > 1.03 AND REF(OPEN,1) > REF(CLOSE,2) AND
ABS(REF(OPEN,1)-REF(CLOSE,1))/REF(CLOSE,1)<0.02 AND
CLOSE/OPEN<0.97 AND CLOSE<REF(CLOSE,2);
★长十字:=CLOSE=OPEN AND HIGH/LOW >1.03;
★垂死十字:=CLOSE=OPEN AND CLOSE=LOW AND CLOSE<>HIGH;
★早晨十字星:=REF(CLOSE,2)/REF(OPEN,2) < 0.95 AND REF(OPEN,1) < REF(CLOSE,2) AND REF(OPEN,1)=REF(CLOSE,1) AND
CLOSE/OPEN>1.05 AND CLOSE>REF(CLOSE,2);
★黄昏十字星:=REF(CLOSE,2)/REF(OPEN,2) > 1.05 AND REF(OPEN,1) > REF(CLOSE,2) AND REF(OPEN,1)=REF(CLOSE,1) AND
CLOSE/OPEN<0.95 AND CLOSE<REF(CLOSE,2);
★射击之星:=MIN(OPEN,CLOSE)=LOW AND HIGH-LOW > 3*(MAX(OPEN,CLOSE)-LOW) AND CLOSE > MA(CLOSE,5);
★倒转锤头:=MIN(OPEN,CLOSE)=LOW AND HIGH-LOW > 3*(MAX(OPEN,CLOSE)-LOW) AND CLOSE < MA(CLOSE,5);
★锤头:=HIGH = MAX(OPEN,CLOSE) AND HIGH-LOW > 3*(HIGH-MIN(OPEN,CLOSE)) AND CLOSE < MA(CLOSE,5);
★吊颈:=HIGH = MAX(OPEN,CLOSE) AND HIGH-LOW > 3*(HIGH-MIN(OPEN,CLOSE)) AND CLOSE>MA(CLOSE,5);
★穿头破脚:=(REF(CLOSE,1)/REF(OPEN,1)>1.03 AND CLOSE/OPEN<0.96 AND CLOSE<REF(OPEN,1) AND OPEN>REF(CLOSE,1))
OR (REF(CLOSE,1)/REF(OPEN,1)<0.97 AND CLOSE/OPEN>1.04 AND CLOSE>REF(OPEN,1) AND OPEN<REF(CLOSE,1));
★乌云盖顶:=REF(CLOSE,1)/REF(OPEN,1)>1.03 AND CLOSE/OPEN<0.97 AND OPEN>REF(CLOSE,1) AND CLOSE<REF(CLOSE,1);
★曙光初现:=REF(CLOSE,1)/REF(OPEN,1)<0.97 AND CLOSE/OPEN>1.03 AND OPEN<REF(CLOSE,1) AND CLOSE>REF(CLOSE,1);
★身怀六甲:=ABS(REF(CLOSE,1)-REF(OPEN,1))/REF(CLOSE,1) > 0.04 AND ABS(CLOSE-OPEN)/CLOSE<0.005 AND
MAX(CLOSE,OPEN) < MAX(REF(CLOSE,1),REF(OPEN,1)) AND MIN(CLOSE,OPEN) > MIN(REF(CLOSE,1),REF(OPEN,1));
★十字胎:=ABS(REF(CLOSE,1)-REF(OPEN,1))/REF(CLOSE,1) > 0.04 AND CLOSE=OPEN AND
CLOSE < MAX(REF(CLOSE,1),REF(OPEN,1)) AND CLOSE > MIN(REF(CLOSE,1),REF(OPEN,1));
★平顶:=ABS(HIGH-REF(HIGH,1))/HIGH<0.001;
★平底:=(ABS(LOW-REF(LOW,1))/LOW<0.001 and abs(ref(low,1)-ref(low,2))/ref(low,1)<=0.001);
★大阳烛:=CLOSE/OPEN>1.05 AND HIGH/LOW < CLOSE/OPEN+0.018;
★红三兵:=REF(CLOSE,2)>REF(OPEN,2) AND REF(CLOSE,1)>REF(OPEN,1) AND CLOSE>OPEN
AND REF(CLOSE,1)>REF(CLOSE,2) AND CLOSE>REF(CLOSE,1);
★双飞乌鸦:=REF(CLOSE,1)<REF(OPEN,1) AND CLOSE<OPEN AND CLOSE/OPEN<0.98;
三日K线模式，第一天长阳，第二天高开收阴，第三天再次高开继续收阴，收盘比前一日收盘价低，预示股价下跌。
特点是第一根阴线的实体部分与上一根K线形成缺口(收盘价高于前一根 K线的收盘价，形成缺口)，
第二根阴线实体部分较长，较为理想的是第二根阴线为跳空高开，然后低收，形成类似穿头破脚的图形，
此形态为双飞乌鸦形态。表示在上升趋势中连续 2日高开，但未能贯彻始终，全部以低收收盘，构成两根阴线，对后市构成压力。
双飞乌鸦的技术含义是上涨无力，短线进入回调或者上涨行情结束。
★孕育线:=REF(CLOSE,2)>REF(OPEN,2) AND (REF(CLOSE,2)-REF(OPEN,2))/REF(OPEN,2)>=2/100  AND REF(OPEN,1)>=REF(CLOSE,1) AND
(REF(OPEN,1)-REF(CLOSE,1))/REF(CLOSE,1)<=2/100 AND REF(OPEN,1)<=REF(CLOSE,2) AND
REF(CLOSE,1)>=REF(OPEN,2) AND C>=OPEN AND
(CLOSE-OPEN)/OPEN>=2/100 AND CLOSE>=REF(OPEN,1) AND OPEN<=REF(CLOSE,1) AND
(MAX(CLOSE,REF(C,2))-MIN(CLOSE,REF(CLOSE,2)))/MIN(CLOSE,REF(CLOSE,2))<=1/100;
★多方炮:=REF(CLOSE,2)>REF(OPEN,2) AND REF(CLOSE,1)<REF(OPEN,1) AND CLOSE>OPEN;
★出水芙蓉:=(OPEN<EMA(C,20) OR OPEN<EMA(C,40) OR OPEN<EMA(C,60)) AND (C>MAX(EMA(C,20),MAX(EMA(C,40),EMA(C,60))))
AND (V/MA(V,30)>1.2 AND C/REF(C,1)>1.049);
★上升三部曲:=REF(CLOSE,4)/REF(OPEN,4)>1.03 AND REF(CLOSE,3)<REF(OPEN,3) AND REF(CLOSE,2)<REF(OPEN,2) AND REF(CLOSE,1)<REF(OPEN,1) AND
REF(LOW,4)<REF(LOW,3) AND REF(LOW,4)<REF(LOW,2) AND REF(LOW,4)<REF(LOW,1) AND REF(HIGH,4)>REF(HIGH,3) AND REF(HIGH,4)>REF(HIGH,2) AND
REF(HIGH,4)>REF(HIGH,1) AND CLOSE/OPEN>1.03 AND CLOSE>REF(CLOSE,4);
★下跌三部曲:= REF(CLOSE,4)/REF(OPEN,4)<0.97 AND REF(CLOSE,3)>REF(OPEN,3) AND REF(CLOSE,2)>REF(OPEN,2) AND REF(CLOSE,1)>REF(OPEN,1) AND REF(LOW,4)<REF(LOW,3) AND
REF(LOW,4)<REF(LOW,2) AND REF(LOW,4)<REF(LOW,1) AND REF(HIGH,4)>REF(HIGH,3) AND REF(HIGH,4)>REF(HIGH,2) AND REF(HIGH,4)>REF(HIGH,1) AND CLOSE/OPEN<0.97 AND
CLOSE<REF(CLOSE,4);
★跳空缺口:=HIGH<REF(LOW,1) OR LOW>REF(HIGH,1);
★三只乌鸦:=REF(CLOSE,2)<REF(OPEN,2) AND REF(CLOSE,1)<REF(OPEN,1) AND CLOSE<OPEN AND REF(CLOSE,1)<REF(CLOSE,2) AND CLOSE<REF(CLOSE,1);
★光脚阴线:=LOW=CLOSE AND HIGH<>LOW;
★光头阳线:=HIGH=CLOSE AND HIGH<>LOW;
★分离:=OPEN=REF(OPEN,1) AND (CLOSE-OPEN)*(REF(CLOSE,1)-REF(OPEN,1))<0;
★长下影:=(MIN(CLOSE,OPEN)-LOW)/(HIGH-LOW)>0.667;
★长上影:=(HIGH-MAX(CLOSE,OPEN))/(HIGH-LOW)>0.667;
★十字星:=CLOSE=OPEN AND HIGH<>LOW;
★大阴烛:=OPEN/CLOSE > 1.05 AND HIGH/LOW < OPEN/CLOSE+0.018;
★好友反攻:=(REF(CLOSE,1)<REF(OPEN,1) AND CLOSE>OPEN AND ABS(CLOSE-REF(CLOSE,1))/CLOSE<0.002)
OR (REF(CLOSE,1)>REF(OPEN,1) AND CLOSE<OPEN AND ABS(CLOSE-REF(CLOSE,1))/CLOSE<0.002);
★倾盆大雨:=REF(C,1)/REF(O,1)>=1.03 AND O<REF(C,1) AND O>REF(O,1) AND C<REF(O,1);
EXPLAIN(★倾盆大雨,'★见顶信号★；'),COLORCYAN;
EXPLAIN(★大阴烛,'★大阴烛★后市向淡,发生逆转；'),COLORCYAN;
EXPLAIN(★好友反攻,'★底部反攻★底部反转；'),COLORRED;
EXPLAIN(★跳空缺口,'★跳空缺口★注意向上还是向下跳空；'),COLORWHITE;
EXPLAIN(★光脚阴线,'★光脚阴线★下跌信号；'),COLORCYAN;
EXPLAIN(★光头阳线,'★光头阳线★后市看涨；'),COLORRED;
EXPLAIN(★三只乌鸦,'★三只乌鸦★可能见顶回落；'),COLORCYAN;
EXPLAIN(★分离,'★分离★注意看涨分离和看跌分离；'),COLORWHITE;
EXPLAIN(★长下影,'★长下影★持续下跌后出现,有可能止跌回升；在升势末期出现,须多加留意；'),COLORRED;
EXPLAIN(★长上影,'★长上影★表明行情上档压力沉重,升势受阻；'),COLORCYAN;
EXPLAIN(★下跌三部曲,'★下跌三部曲★下跌信号；'),COLORRED;
EXPLAIN(★上升三部曲,'★上升三部曲★上涨信号；'),COLORCYAN;
EXPLAIN(★早晨之星,'★早晨之星★见底回升；'),COLORRED;
EXPLAIN(★黄昏之星,'★黄昏之星★见顶回落；'),COLORCYAN;
EXPLAIN(★十字星,'★十字星★有转向意味,注意股价位置在顶部还是底部；'),COLORWHITE;
EXPLAIN(★长十字,'★长十字★注意在顶部还是底部；'),COLORWHITE;
EXPLAIN(★垂死十字,'★垂死十字★下跌信号；'),COLORCYAN;
EXPLAIN(★早晨十字星,'★早晨十字星★上涨信号，见底回升；'),COLORRED;
EXPLAIN(★黄昏十字星,'★黄昏十字星★下跌信号，见顶回落；'),COLORCYAN;
EXPLAIN(★射击之星,'★射击之星★可能见顶回落,可靠性低；'),COLORCYAN;
EXPLAIN(★倒转锤头,'★倒转锤头★可能见底回升；'),COLORRED;
EXPLAIN(★锤头,'★锤头★可能见底回升,如有量配合,信号强烈；'),COLORRED;
EXPLAIN(★吊颈,'★吊颈★上升行情中见顶回落,顶部出现,见顶信号；'),COLORCYAN;
EXPLAIN(★平顶,'★平顶★温和的反转；'),COLORCYAN;
EXPLAIN(★穿头破脚,'★穿头破脚★顶部出现,见顶回落信号；'),COLORCYAN;
EXPLAIN(★乌云盖顶,'★乌云盖顶★见顶回落信号；'),COLORCYAN;
EXPLAIN(★曙光初现,'★曙光初现★后市见底回升；'),COLORRED;
EXPLAIN(★身怀六甲,'★身怀六甲★出现在底部,是见底回升信号；出现在顶部,是见顶回落信号；'),COLORRED;
EXPLAIN(★十字胎,'★十字胎★在底部出现有上涨可能，在中间出现有可能是上涨中继，顶部出现是复合见顶信号；'),COLORRED;
EXPLAIN(★平底,'★平底★温和的反转；'),COLORRED;
EXPLAIN(★大阳烛,'★大阳烛★看涨；'),COLORRED;
EXPLAIN(★红三兵,'★红三兵★每日收盘价上移,表示可能见底回升；'),COLORRED;
EXPLAIN(★双飞乌鸦,'★双飞乌鸦★行情将见顶回落；'),COLORCYAN;
EXPLAIN(★孕育线,'★孕育线★注意股价位置；'),COLORWHITE;
EXPLAIN(★多方炮,'★皆有可能★在底部出现有上涨可能，在中间出现有可能是上涨中继，顶部出现是复合见顶信号；'),COLORRED;
EXPLAIN(★出水芙蓉,'★见底回升★；'),COLORRED;

量的变化率：PTV（Percent Turn of Volume)
量价变化率：PVP=(H-L)/C * PTV
"""
from .indicator_template import ArrayManager


class KPattern:
    def __init__(self, bars: ArrayManager):
        self.bars = bars

    def morning_star(self, r=0.005):
        """
        早晨之星
        REF(CLOSE,2)/REF(OPEN,2) < 0.95 AND REF(OPEN,1) < REF(CLOSE,2)
        AND ABS(REF(OPEN,1)-REF(CLOSE,1))/REF(CLOSE,1)<0.03 AND
        CLOSE/OPEN>1.05 AND CLOSE>REF(CLOSE,2);
        """
        bars = self.bars
        if bars.c[-3] / bars.o[-3] < 1 - r and bars.o[-2] < bars.c[-3] \
                and abs(bars.o[-2] - bars.c[-2]) < r * bars.c[-2] \
                and bars.c[-1] / bars.o[-1] > 1 + r and bars.c[-1] > bars.c[-3]:
            return 1
        else:
            return 0

    def evening_star(self, r=0.005):
        """
        ★黄昏之星:=REF(CLOSE,2)/REF(OPEN,2) > 1.03 AND REF(OPEN,1) > REF(CLOSE,2) AND
        ABS(REF(OPEN,1)-REF(CLOSE,1))/REF(CLOSE,1)<0.02 AND
        CLOSE/OPEN<0.97 AND CLOSE<REF(CLOSE,2);
        """
        c = self.bars.c
        o = self.bars.o
        if c[-3] / o[-3] > 1 + r and o[-2] > c[-3] and abs(o[-2] - c[-2]) / c[-2] < r and c[-1] / o[-1] < 1 - r and c[
            -1] < c[-2]:
            return 1
        else:
            return 0

    def long_cross(self, r=0.005):
        """
        ★长十字:=CLOSE=OPEN AND HIGH/LOW >1.03;
        """
        bars = self.bars
        if bars.c[-1] == bars.o[-1] and bars.h[-1] / bars.l[-1] > 1 + r:
            return 1
        else:
            return 0

    def dying_cross(self):
        """
        ★垂死十字:=CLOSE=OPEN AND CLOSE=LOW AND CLOSE<>HIGH;
        """
        bars = self.bars
        if bars.c[-1] == bars.o[-1] and bars.c[-1] == bars.l[-1] and bars.h[-1] != bars.l[-1]:
            return 1
        else:
            return 0

    def morning_cross(self, r=0.005):
        """
        ★早晨十字星:=REF(CLOSE,2)/REF(OPEN,2) < 0.95 AND REF(OPEN,1) < REF(CLOSE,2)
        AND REF(OPEN,1)=REF(CLOSE,1) AND
        CLOSE/OPEN>1.05 AND CLOSE>REF(CLOSE,2);

        """
        c = self.bars.c
        o = self.bars.o
        if c[-3] / o[-3] < 1 - r and o[-2] < c[-3] and o[-2] == c[-2] and c[-1] / o[-1] > 1 + r and c[-1] > c[-3]:
            return 1
        else:
            return 0

    def evening_cross(self, r=0.005):
        """
        ★黄昏十字星:=REF(CLOSE,2)/REF(OPEN,2) > 1.05 AND REF(OPEN,1) > REF(CLOSE,2)
        AND REF(OPEN,1)=REF(CLOSE,1) AND
        CLOSE/OPEN<0.95 AND CLOSE<REF(CLOSE,2);

        """
        c = self.bars.c
        o = self.bars.o
        if c[-3] / o[-3] > 1 + r and o[-2] > c[-3] and o[-2] == c[-2] and c[-1] / o[-1] < 1 - r and c[-1] < c[-3]:
            return 1
        else:
            return 0

    def shotting_star(self, r=3.0):
        """
        ★射击之星:=MIN(OPEN,CLOSE)=LOW AND HIGH-LOW > 3*(MAX(OPEN,CLOSE)-LOW)
        AND CLOSE > MA(CLOSE,5);

        """
        bars = self.bars
        o = bars.o[-1]
        h = bars.h[-1]
        l = bars.l[-1]
        c = bars.c[-1]
        if l == min(o, c) and h - l > r * (max(o, c) - l) and c > bars.c[-5:].sum() / 5:
            return 1
        else:
            return 0

    def hammer_head_return(self, r=3.0):
        """
        ★倒转锤头:=MIN(OPEN,CLOSE)=LOW AND HIGH-LOW > 3*(MAX(OPEN,CLOSE)-LOW)
        AND CLOSE < MA(CLOSE,5);

        """
        bars = self.bars
        o = bars.o[-1]
        h = bars.h[-1]
        l = bars.l[-1]
        c = bars.c[-1]
        if l == min(o, c) and h - l > r * (max(o, c) - l) and c < bars.c[-5:].sum() / 5:
            return 1
        else:
            return 0

    def hammer_head(self, r=3.0):
        """
        ★锤头:=HIGH = MAX(OPEN,CLOSE) AND HIGH-LOW > 3*(HIGH-MIN(OPEN,CLOSE))
        AND CLOSE < MA(CLOSE,5);
        """
        bars = self.bars
        o = bars.o[-1]
        h = bars.h[-1]
        l = bars.l[-1]
        c = bars.c[-1]
        if l == max(o, c) and h - l > r * (h - min(o, c)) and c < bars.c[-5:].sum() / 5:
            return 1
        else:
            return 0

    def diao_jing(self, r=3.0):
        """
★吊颈:=HIGH = MAX(OPEN,CLOSE) AND HIGH-LOW > 3*(HIGH-MIN(OPEN,CLOSE))
AND CLOSE>MA(CLOSE,5);
        """
        bars = self.bars
        o = bars.o[-1]
        h = bars.h[-1]
        l = bars.l[-1]
        c = bars.c[-1]
        if h == max(o, c) and h - l > r * (h - min(o, c)) and c > bars.c[-5:].sum() / 5:
            return 1
        else:
            return 0

    def chuan_tou_po_jiao(self, r=.005):
        """
★穿头破脚:=(REF(CLOSE,1)/REF(OPEN,1)>1.03 AND CLOSE/OPEN<0.96
AND CLOSE<REF(OPEN,1) AND OPEN>REF(CLOSE,1))
OR (REF(CLOSE,1)/REF(OPEN,1)<0.97 AND CLOSE/OPEN>1.04 AND CLOSE>REF(OPEN,1) AND OPEN<REF(CLOSE,1));

        """
        bars = self.bars
        o = bars.o
        c = bars.c
        if (c[-2] / o[-2] > 1 + r and c[-1] / o[-1] < 1 - r and c[-1] < o[-2] and o[-1] > c[-2]) or \
                (c[-2] / o[-2] < 1 - r and c[-1] / o[-1] > 1 + r and c[-1] > o[-2] and o[-1] < c[-2]):
            return 1
        else:
            return 0

    def wu_yun_gai_ding(self, r=.005):
        """
★乌云盖顶:=REF(CLOSE,1)/REF(OPEN,1)>1.03 AND CLOSE/OPEN<0.97 AND OPEN>REF(CLOSE,1) AND CLOSE<REF(CLOSE,1);
        """
        bars = self.bars
        o = bars.o
        h = bars.h
        l = bars.l
        c = bars.c
        if (c[-2] / o[-2] > 1 + r and c[-1] / o[-1] < 1 - r and c[-1] < o[-2] and o[-1] > c[-2]):
            return 1
        else:
            return 0

    def xu_guang_chu_xian(self, r=.005):
        """
★曙光初现:=REF(CLOSE,1)/REF(OPEN,1)<0.97 AND CLOSE/OPEN>1.03 AND OPEN<REF(CLOSE,1) AND CLOSE>REF(CLOSE,1);
        """
        bars = self.bars
        o = bars.o
        c = bars.c
        if (c[-2] / o[-2] > 1 + r and c[-1] / o[-1] < 1 - r and c[-1] < o[-2] and o[-1] > c[-2]):
            return 1
        else:
            return 0

    def shen_huai_liu_jia(self, r=.005):
        """
★身怀六甲:=ABS(REF(CLOSE,1)-REF(OPEN,1))/REF(CLOSE,1) > 0.04 AND ABS(CLOSE-OPEN)/CLOSE<0.005 AND
MAX(CLOSE,OPEN) < MAX(REF(CLOSE,1),REF(OPEN,1)) AND MIN(CLOSE,OPEN) > MIN(REF(CLOSE,1),REF(OPEN,1));

        """
        bars = self.bars
        o = bars.o
        h = bars.h
        l = bars.l
        c = bars.c
        if (abs(1 - o[-2] / c[-2]) > r and abs(1 - o[-1] / c[-1]) < r / 10.
            and max(c[-1], o[-1]) < max(o[-2], c[-2])
            and min(o[-1], c[-1]) > min(c[-2]), o[-2]):
            return 1
        else:
            return 0


def livingLine(K, c):
    """生命线
    :param K :K线序列
    :params c: 换手率序列
    :return : 生命线
    """
    p
